package com.yunwaikeji.gy_tool_library.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;

import com.yunwaikeji.gy_tool_library.R;
import com.yunwaikeji.gy_tool_library.info.GYDisplayInfo;
import com.yunwaikeji.gy_tool_library.info.GYStatisticsInfo;
import com.yunwaikeji.gy_tool_library.utils.display.GYDisplayUtils;
import com.yunwaikeji.gy_tool_library.utils.GYPaintUtils;

import com.yunwaikeji.gy_tool_library.view.GYView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 曲线、柱形、扇形 统计图
 */
public class GYStatisticsView extends GYView implements GYStatisticsInfo {
    public GYStatisticsView(Context context) {
        super(context);
        init(null);
    }

    public GYStatisticsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public GYStatisticsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    public GYStatisticsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs);
    }

    private int layout_width = WRAP_CONTENT;
    private int layout_height = WRAP_CONTENT;
    //    private float layout_weight = 0;
    private int statisticsDisplayStyle = DisplayStyle.CURVE;//显示样式，默认曲线

    private int xTextSize = GYDisplayUtils.sp2px(getContext(), 14);//X轴文字大小
    private int xTextColor = Color.BLACK;//X轴文字颜色
    private float xLineWidth = 1;//X轴线宽度
    private int xLineColor = Color.BLACK;//X轴线颜色
    private float xTextLineSpacing = GYDisplayUtils.dp2px(getContext(), 7);//X轴文字和轴线的间距
    private float xSpacing = GYDisplayUtils.dp2px(getContext(), 30);//X轴间距
    private float xFirstSpacing = WRAP_CONTENT;//X轴头部间距
    private float xLastSpacing = 0;//X轴尾部间距
    private String xPointText;//X轴原点文字
    private boolean xSpacingFullParent = false;//X轴间距充满父布局平分

    private int yTextSize = xTextSize;//Y轴文字大小
    private int yTextColor = xTextColor;//Y轴文字颜色
    private float yLineWidth = xLineWidth;//Y轴线宽度
    private int yLineColor = xLineColor;//Y轴线颜色
    private float yTextLineSpacing = GYDisplayUtils.dp2px(getContext(), 5);//Y轴文字和轴线的间距
    private float ySpacing = GYDisplayUtils.dp2px(getContext(), 20);//Y轴间距
    private float yFirstSpacing = WRAP_CONTENT;//Y轴头部间距
    private float yLastSpacing = 0;//Y轴尾部间距
    private String yPointText;//Y轴原点文字
    private boolean ySpacingFullParent = false;//Y轴间距充满父布局平分

    private int yFirstNumber;//Y轴首number
    private int yAddNumber;//Y轴每次递增显示的number
    private int yNumberCount;//Y轴number总数，递增多少个

    private Drawable curveSpot;//曲线点图
    private float curveSpotWidth = WRAP_CONTENT;//曲线点图宽
    private float curveSpotHeight = WRAP_CONTENT;//曲线点图高
    private int curveSpotDisplayStyle = GYDisplayInfo.DisplayStyle.CIRCLE_CENTER;//曲线点显示样式
    private int curveColor = Color.GREEN;//曲线颜色
    private float curveWidth = 1;//曲线宽度
    private int curveFirstNumber = UNKNOWN;//曲线首点数值，默认不显示
    private int curveLastNumber = UNKNOWN;//曲线尾点数值，默认不显示
    private Drawable curveBackground;//曲线背景图
    private int tipLocation = TipLocation.TOP;//提示信息显示位置，默认顶部
    private int tipTextSize = GYDisplayUtils.sp2px(getContext(), 14);//提示信息文字大小
    private int tipTextColor = Color.BLACK;//提示信息文字颜色
    private float tipTextMargin = GYDisplayUtils.dp2px(getContext(), 1);//提示信息文字边距

    private int circleDisplay = SectorDisplay.CENTER;//扇形图显示位置，默认居中
    private int sectorSpacingDegree = 3;//扇形之间的间距度数，总360度
    private int sectorStartDegree = 0;//扇形开始度数，默认水平为0，总360度

    private final List<String> xStringList = new ArrayList<>();//X轴文字列表
    private final List<Long> yNumberList = new ArrayList<>();//Y轴数值列表
    private final List<Long> numberList = new ArrayList<>();//Y轴具体的数值列表
    private final List<Integer> sectorColorList = new ArrayList<>();//扇形颜色列表

    private void init(AttributeSet attributeSet) {
        int textSize = WRAP_CONTENT;
        int textColor = WRAP_CONTENT;
        int lineSize = WRAP_CONTENT;
        int lineColor = WRAP_CONTENT;
        if (attributeSet != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attributeSet, R.styleable.GYStatisticsView);
            layout_width = typedArray.getLayoutDimension(R.styleable.GYStatisticsView_android_layout_width, layout_width);
            layout_height = typedArray.getLayoutDimension(R.styleable.GYStatisticsView_android_layout_height, layout_height);
//            layout_weight = typedArray.getFloat(R.styleable.GYStatisticsView_android_layout_weight, layout_weight);
            setDisplayStyle(typedArray.getInteger(R.styleable.GYStatisticsView_statisticsDisplayStyle, statisticsDisplayStyle));
            xTextSize = typedArray.getDimensionPixelSize(R.styleable.GYStatisticsView_xTextSize, xTextSize);
            xTextColor = typedArray.getColor(R.styleable.GYStatisticsView_xTextColor, xTextColor);
            xLineWidth = typedArray.getDimension(R.styleable.GYStatisticsView_xLineWidth, xLineWidth);
            xLineColor = typedArray.getColor(R.styleable.GYStatisticsView_xLineColor, xLineColor);
            xTextLineSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_xTextLineSpacing, xTextLineSpacing);
            yTextSize = typedArray.getDimensionPixelSize(R.styleable.GYStatisticsView_yTextSize, yTextSize);
            yTextColor = typedArray.getColor(R.styleable.GYStatisticsView_yTextColor, yTextColor);
            yLineWidth = typedArray.getDimension(R.styleable.GYStatisticsView_yLineWidth, yLineWidth);
            yLineColor = typedArray.getColor(R.styleable.GYStatisticsView_yLineColor, yLineColor);
            yTextLineSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_yTextLineSpacing, yTextLineSpacing);
            textSize = typedArray.getDimensionPixelSize(R.styleable.GYStatisticsView_textSize, textSize);
            textColor = typedArray.getColor(R.styleable.GYStatisticsView_textColor, textColor);
            lineSize = typedArray.getDimensionPixelSize(R.styleable.GYStatisticsView_lineSize, lineSize);
            lineColor = typedArray.getColor(R.styleable.GYStatisticsView_lineColor, lineColor);
            xSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_xSpacing, xSpacing);
            xFirstSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_xFirstSpacing, xFirstSpacing);
            xLastSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_xLastSpacing, xLastSpacing);
            xSpacingFullParent = typedArray.getBoolean(R.styleable.GYStatisticsView_xSpacingFullParent, xSpacingFullParent);

            ySpacing = typedArray.getDimension(R.styleable.GYStatisticsView_ySpacing, ySpacing);
            yFirstSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_yFirstSpacing, yFirstSpacing);
            yLastSpacing = typedArray.getDimension(R.styleable.GYStatisticsView_yLastSpacing, yLastSpacing);
            xPointText = typedArray.getString(R.styleable.GYStatisticsView_xPointText);
            yPointText = typedArray.getString(R.styleable.GYStatisticsView_yPointText);
            ySpacingFullParent = typedArray.getBoolean(R.styleable.GYStatisticsView_ySpacingFullParent, ySpacingFullParent);

            yFirstNumber = typedArray.getInteger(R.styleable.GYStatisticsView_yFirstNumber, yFirstNumber);
            yAddNumber = typedArray.getInteger(R.styleable.GYStatisticsView_yAddNumber, yAddNumber);
            yNumberCount = typedArray.getInteger(R.styleable.GYStatisticsView_yNumberCount, yNumberCount);
            curveSpot = typedArray.getDrawable(R.styleable.GYStatisticsView_curveSpot);
            curveSpotWidth = typedArray.getDimension(R.styleable.GYStatisticsView_curveSpotWidth, curveSpotWidth);
            curveSpotHeight = typedArray.getDimension(R.styleable.GYStatisticsView_curveSpotHeight, curveSpotHeight);
            curveColor = typedArray.getColor(R.styleable.GYStatisticsView_curveColor, curveColor);
            curveWidth = typedArray.getDimension(R.styleable.GYStatisticsView_curveWidth, curveWidth);
            curveFirstNumber = typedArray.getInteger(R.styleable.GYStatisticsView_curveFirstNumber, curveFirstNumber);
            curveLastNumber = typedArray.getInteger(R.styleable.GYStatisticsView_curveLastNumber, curveFirstNumber);
            curveBackground = typedArray.getDrawable(R.styleable.GYStatisticsView_curveBackground);
            tipLocation = typedArray.getInteger(R.styleable.GYStatisticsView_tipLocationStatistics, tipLocation);
            tipTextSize = typedArray.getDimensionPixelSize(R.styleable.GYStatisticsView_tipTextSize, tipTextSize);
            tipTextColor = typedArray.getColor(R.styleable.GYStatisticsView_tipTextColor, tipTextColor);
            tipTextMargin = typedArray.getDimension(R.styleable.GYStatisticsView_tipTextMargin, tipTextMargin);
            circleDisplay = typedArray.getInteger(R.styleable.GYStatisticsView_sectorDisplay, circleDisplay);
            sectorSpacingDegree = typedArray.getInteger(R.styleable.GYStatisticsView_sectorSpacingDegree, sectorSpacingDegree);
            sectorStartDegree = typedArray.getInteger(R.styleable.GYStatisticsView_sectorStartDegree, sectorStartDegree);
            typedArray.recycle();
        }
        if (textSize != WRAP_CONTENT) {
            xTextSize = textSize;
            yTextSize = textSize;
            tipTextSize = textSize;
        }
        if (textColor != WRAP_CONTENT) {
            xTextColor = textColor;
            yTextColor = textColor;
            tipTextColor = textColor;
        }
        if (lineSize != WRAP_CONTENT) {
            xLineWidth = lineSize;
            yLineWidth = lineSize;
        }
        if (lineColor != WRAP_CONTENT) {
            xLineColor = lineColor;
            yLineColor = lineColor;
        }
        if (paint == null) {
            paint = new Paint();
        }
    }

    public GYStatisticsView setDisplayStyle(@DisplayStyle int statisticsDisplayStyle) {
        this.statisticsDisplayStyle = statisticsDisplayStyle;
        return this;
    }

    public GYStatisticsView refreshView() {
        requestLayout();
        invalidate();
        return this;
    }

    public GYStatisticsView clearXStrings() {
        xStringList.clear();
        return this;
    }

    public GYStatisticsView addXStrings(List<String> xStringList) {
        this.xStringList.addAll(xStringList);
        return this;
    }

    public GYStatisticsView addXStrings(String... xStrings) {
        return addXStrings(Arrays.asList(xStrings));
    }

    public GYStatisticsView setXStrings(List<String> xStringList) {
        this.xStringList.clear();
        return addXStrings(xStringList);
    }

    public GYStatisticsView setXStrings(String... xStrings) {
        return setXStrings(Arrays.asList(xStrings));
    }

    public GYStatisticsView clearYNumbers() {
        yNumberList.clear();
        return this;
    }

    public GYStatisticsView addYNumbers(List<Long> yNumberList) {
        this.yNumberList.addAll(yNumberList);
        for (int i = this.yNumberList.size() - 1; i >= 0; i--) {
            if (this.yNumberList.get(i) == 0) {
                this.yNumberList.remove(i);
            }
        }
        Collections.sort(this.yNumberList);
        return this;
    }

    public GYStatisticsView addYNumbers(Long... yNumbers) {
        return addYNumbers(Arrays.asList(yNumbers));
    }

    public GYStatisticsView setYNumbers(List<Long> yNumberList) {
        this.yNumberList.clear();
        return addYNumbers(yNumberList);
    }

    public GYStatisticsView setYNumbers(Long... yNumbers) {
        return setYNumbers(Arrays.asList(yNumbers));
    }

    public GYStatisticsView clearNumbers() {
        numberList.clear();
        return this;
    }

    public GYStatisticsView addNumbers(List<Long> numberList) {
        this.numberList.addAll(numberList);
        return this;
    }

    public GYStatisticsView addNumbers(Long... numbers) {
        return addNumbers(Arrays.asList(numbers));
    }

    public GYStatisticsView setNumbers(List<Long> numberList) {
        this.numberList.clear();
        return addNumbers(numberList);
    }

    public GYStatisticsView setNumbers(Long... numbers) {
        return setNumbers(Arrays.asList(numbers));
    }

    public GYStatisticsView setXPointText(String xPointText) {
        this.xPointText = xPointText;
        return this;
    }

    public GYStatisticsView setYPointText(String yPointText) {
        this.yPointText = yPointText;
        return this;
    }

    public GYStatisticsView setYFirstNumber(int yFirstNumber) {
        this.yFirstNumber = yFirstNumber;
        return initYList();
    }

    public GYStatisticsView setYAddNumber(int yAddNumber) {
        this.yAddNumber = yAddNumber;
        return initYList();
    }

    public GYStatisticsView setYNumberCount(int yNumberCount) {
        this.yNumberCount = yNumberCount;
        return initYList();
    }

    private GYStatisticsView initYList() {
        yNumberList.clear();
        for (int i = 0; i < yNumberCount; i++) {
            yNumberList.add(yFirstNumber + ((long) yAddNumber * i));
        }
        return this;
    }

    public GYStatisticsView setCurveBackground(Drawable curveBackground) {
        this.curveBackground = curveBackground;
        return this;
    }

    public GYStatisticsView setCurveSpot(Drawable curveSpot) {
        this.curveSpot = curveSpot;
        return this;
    }

    public GYStatisticsView setCurveFirstNumber(int curveFirstNumber) {
        this.curveFirstNumber = curveFirstNumber;
        return this;
    }

    public GYStatisticsView setCurveLastNumber(int curveLastNumber) {
        this.curveLastNumber = curveLastNumber;
        return this;
    }

    /**
     * 扇形颜色列表
     *
     * @return
     */
    public GYStatisticsView addSectorColors(List<Integer> sectorColorList) {
        this.sectorColorList.addAll(sectorColorList);
        return this;
    }

    public GYStatisticsView addSectorColors(Integer... sectorColors) {
        return addSectorColors(Arrays.asList(sectorColors));
    }

    public GYStatisticsView setSectorColors(List<Integer> sectorColorList) {
        this.sectorColorList.clear();
        return addSectorColors(sectorColorList);
    }

    public GYStatisticsView setSectorColors(Integer... sectorColors) {
        return setSectorColors(Arrays.asList(sectorColors));
    }

    public GYStatisticsView setTipLocation(int tipLocation) {
        this.tipLocation = tipLocation;
        return this;
    }

    public int getTipLocation() {
        return tipLocation;
    }

    public int getTipTextSize() {
        return tipTextSize;
    }

    public GYStatisticsView setTipTextSize(int tipTextSize) {
        this.tipTextSize = tipTextSize;
        return this;
    }

    public int getTipTextColor() {
        return tipTextColor;
    }

    public GYStatisticsView setTipTextColor(int tipTextColor) {
        this.tipTextColor = tipTextColor;
        return this;
    }

    public float getTipTextMargin() {
        return tipTextMargin;
    }

    public GYStatisticsView setTipTextMargin(float tipTextMargin) {
        this.tipTextMargin = tipTextMargin;
        return this;
    }

    private float pointX;
    private float pointY;
    private Paint paint;
    private float yTextHeight;
    private float yTextMaxWidth;
    private Paint.FontMetrics xFontMetrics;
    private Paint.FontMetrics yFontMetrics;

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measuredWidth = getMeasuredWidth();
        int measuredHeight = getMeasuredHeight();
        switch (statisticsDisplayStyle) {
            case DisplayStyle.CURVE://曲线
            case DisplayStyle.COLUMN://柱形
                yTextMaxWidth = 0;
                pointX = getPaddingLeft();
                pointY = getPaddingTop();
                //计算原点X坐标
                paint.setTextSize(yTextSize);
                yFontMetrics = paint.getFontMetrics();
                yTextHeight = yFontMetrics.bottom - yFontMetrics.top;
                for (Long yNumber : yNumberList) {
                    String ys = String.valueOf(yNumber);
                    Rect rect = new Rect();
                    paint.getTextBounds(ys, 0, ys.length(), rect);
                    yTextMaxWidth = Math.max(rect.width(), yTextMaxWidth);
                }
                if (!TextUtils.isEmpty(yPointText)) {
                    Rect rect = new Rect();
                    paint.getTextBounds(yPointText, 0, yPointText.length(), rect);
                    yTextMaxWidth = Math.max(rect.width(), yTextMaxWidth);
                }
                if (!TextUtils.isEmpty(xPointText)) {
                    paint.setTextSize(xTextSize);
                    Rect rect = new Rect();
                    paint.getTextBounds(xPointText, 0, xPointText.length(), rect);
                    yTextMaxWidth = Math.max(rect.width() / 2, yTextMaxWidth);
                }
                if (yNumberList.size() > 0) {
                    pointX += yTextLineSpacing;
                }
                pointX += yTextMaxWidth + yLineWidth / 2 + getPaddingLeft();
                //计算原点Y坐标
                pointY += yLastSpacing + yFirstSpacing() + xLineWidth / 2 + getPaddingTop();
                if (yNumberList.size() > 0) {
                    pointY += (yNumberList.size() - 1) * ySpacing + (int) (yTextHeight / 2);
                }
                //测量控件宽
                float xLastTextWidth = 0;
                if (xStringList.size() > 0) {
                    Rect rect = new Rect();
                    String xLastS = xStringList.get(xStringList.size() - 1);
                    paint.getTextBounds(xLastS, 0, xLastS.length(), rect);
                    xLastTextWidth = rect.width();
                }
                if (layout_width == WRAP_CONTENT) {
                    paint.setTextSize(xTextSize);
                    measuredWidth = (int) (pointX + yLineWidth / 2 + xFirstSpacing() + xLastSpacing) + getPaddingRight();
                    if (xStringList.size() > 0) {
                        measuredWidth += (xStringList.size() - 1) * xSpacing + xLastTextWidth / 2;
                    }
                } else {
                    float xSpacingAll = measuredWidth - pointX - getPaddingRight() - xLastSpacing;
                    if (xStringList.size() > 0) {
                        xSpacingAll -= xLastTextWidth / 2;
                    }
                    if (xFirstSpacing == WRAP_CONTENT) {
                        if (xStringList.size() == 0) {
                            xSpacing = xSpacingAll;
                        } else {
                            xSpacing = xSpacingAll / xStringList.size();
                        }
                    } else {
                        xSpacingAll -= xFirstSpacing;
                        if (xStringList.size() > 0) {
                            xSpacing = xSpacingAll / (xStringList.size() - 1);
                        }
                    }
                }
                //测量控件高
                paint.setTextSize(xTextSize);
                xFontMetrics = paint.getFontMetrics();
                float yTextHeight = xFontMetrics.bottom - xFontMetrics.top;
                if (layout_height == WRAP_CONTENT) {
                    measuredHeight = (int) (pointY + xLineWidth / 2) + getPaddingBottom();
                    if (xStringList.size() > 0) {
                        measuredHeight += xTextLineSpacing + (int) yTextHeight + (int) (yTextHeight / 2);
                    }
                } else {
                    float ySpacingAll = pointY - getPaddingTop() - yLastSpacing;
                    if (yNumberList.size() > 0) {
                        ySpacingAll -= yTextHeight / 2;
                    }
                    if (yFirstSpacing == WRAP_CONTENT) {
                        if (yNumberList.size() == 0) {
                            ySpacing = ySpacingAll;
                        } else {
                            ySpacing = ySpacingAll / yNumberList.size();
                        }
                    } else {
                        ySpacingAll -= yFirstSpacing;
                        if (yNumberList.size() > 0) {
                            ySpacing = ySpacingAll / (yNumberList.size() - 1);
                        }
                    }
                }
                break;
            case DisplayStyle.SECTOR://扇形
                if (layout_width == WRAP_CONTENT) {
                    measuredWidth = GYDisplayUtils.dp2px(getContext(), 80);
                }
                if (layout_height == WRAP_CONTENT) {
                    measuredHeight = GYDisplayUtils.dp2px(getContext(), 80);
                }
                break;
        }
        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.TRANSPARENT);
        switch (statisticsDisplayStyle) {
            case DisplayStyle.CURVE://曲线图
            case DisplayStyle.COLUMN://柱形图
                drawXY(canvas);
                break;
            case DisplayStyle.SECTOR://扇形图
                drawSector(canvas);
                break;
        }
    }

    private List<Float> yTextYList = new ArrayList<>();

    private Bitmap spotBitmap;

    /**
     * 画XY轴图
     *
     * @param canvas
     */
    private void drawXY(Canvas canvas) {
        //画 X 轴线
        paint.setStyle(Paint.Style.FILL);
        if (xLineWidth > 0) {
            paint.setColor(xLineColor);
            paint.setStrokeWidth(xLineWidth);
            canvas.drawLine(pointX, pointY, getWidth() - getPaddingRight(), pointY, paint);
        }
        //画 Y 轴线
        if (yLineWidth > 0) {
            paint.setColor(yLineColor);
            paint.setStrokeWidth(yLineWidth);
            canvas.drawLine(pointX, pointY, pointX, getPaddingTop(), paint);
        }
        //写X轴文字
        paint.setColor(xTextColor);
        paint.setTextSize(xTextSize);
        paint.setTextAlign(Paint.Align.CENTER);
        float xFirstTextX = pointX + yLineWidth / 2 + xFirstSpacing();
        float xTextY = pointY + xLineWidth / 2 + xTextLineSpacing - xFontMetrics.top;
        if (!TextUtils.isEmpty(xPointText)) {
            canvas.drawText(xPointText, pointX, xTextY, paint);
        }
        List<Float> xTextXList = new ArrayList<>();
        for (int i = 0; i < xStringList.size(); i++) {
            float xTextX = xFirstTextX + xSpacing * i;
            xTextXList.add(xTextX);
            canvas.drawText(xStringList.get(i), xTextX, xTextY, paint);
        }
        //写Y轴文字
        paint.setColor(yTextColor);
        paint.setTextSize(yTextSize);
        paint.setTextAlign(Paint.Align.RIGHT);
        float yLastTextY = getPaddingTop() + yLastSpacing + (-yFontMetrics.top - yFontMetrics.bottom) / 2 + (int) (yTextHeight / 2);
        yTextYList.clear();
        for (int i = 0; i < yNumberList.size(); i++) {
            float yTextY = yLastTextY + ySpacing * (yNumberList.size() - 1 - i);
            yTextYList.add(yTextY);
            if (i == 0 && !TextUtils.isEmpty(yPointText)) {
                canvas.drawText(yPointText, yTextMaxWidth, yTextY + yFirstSpacing(), paint);
            }
            canvas.drawText(String.valueOf(yNumberList.get(i)), yTextMaxWidth, yTextY, paint);
        }
        switch (statisticsDisplayStyle) {
            case DisplayStyle.CURVE://画曲线
                if (yNumberList.size() > 0) {
                    //计算每个点的坐标
                    List<SpotBean> spotBeanList = new ArrayList<>();
                    for (int i = 0; i < xTextXList.size(); i++) {
                        if (i < numberList.size()) {
                            float spotX = xTextXList.get(i);
                            spotBeanList.add(SpotBean.newInstance().setX(spotX).setY(getY(numberList.get(i))).setDrawSpot(true).setNumber(numberList.get(i)));
                        } else {
                            break;
                        }
                    }
                    if (curveFirstNumber != UNKNOWN) {
                        spotBeanList.add(0, SpotBean.newInstance().setX(pointX + yLineWidth / 2).setY(curveFirstNumber == WRAP_CONTENT ? (spotBeanList.size() == 0 ? 0 : spotBeanList.get(0).getY()) : curveFirstNumber));
                    }
                    if (curveLastNumber != UNKNOWN) {
                        spotBeanList.add(SpotBean.newInstance().setX(getWidth() - getPaddingRight()).setY(curveLastNumber == WRAP_CONTENT ? (spotBeanList.size() == 0 ? 0 : spotBeanList.get(spotBeanList.size() - 1).getY()) : curveLastNumber));
                    }
                    //画背景图
                    if (curveBackground != null) {
                        Path curveBgPath = curvePath(spotBeanList);
                        curveBgPath.lineTo(spotBeanList.get(spotBeanList.size() - 1).getX(), pointY - xLineWidth / 2);
                        curveBgPath.lineTo(spotBeanList.get(0).getX(), pointY - xLineWidth / 2);
                        curveBgPath.lineTo(spotBeanList.get(0).getX(), spotBeanList.get(0).getY());
                        Rect rect = new Rect(Math.round(pointX + yLineWidth / 2), getPaddingTop(), getWidth() - getPaddingRight(), Math.round(pointY - xLineWidth / 2));
                        int width = rect.right - rect.left;
                        int height = rect.bottom - rect.top;
                        if (width > 0 && height > 0) {
                            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
                            Canvas canvas1 = new Canvas(bitmap);
                            canvas1.clipPath(curveBgPath);
                            canvas1.drawBitmap(GYDisplayUtils.toBitmap(curveBackground, width, height), null, rect, paint);
                            paint.setColor(PAINT_NORMAL_COLOR);
                            canvas.drawBitmap(bitmap, 0, 0, paint);
                        }
                    }
                    //画曲线
                    paint.setColor(curveColor);
                    paint.setStrokeWidth(curveWidth);
                    paint.setStyle(Paint.Style.STROKE);
                    paint.setAntiAlias(true);
                    canvas.drawPath(curvePath(spotBeanList), paint);
                    //画点
                    if (curveSpot != null) {
                        curveSpot = GYDisplayUtils.newBuilder()
                                .setNormal(curveSpot)
                                .setDisplayStyle(curveSpotDisplayStyle)
                                .buildDrawable();
                        float width;
                        float height;
                        if (curveSpotWidth == WRAP_CONTENT) {
                            if (curveSpot.getIntrinsicHeight() < 0) {
                                width = GYDisplayUtils.dp2px(getContext(), 8);
                            } else {
                                width = curveSpot.getIntrinsicWidth();
                            }
                        } else {
                            width = curveSpotWidth;
                        }
                        if (curveSpotHeight == WRAP_CONTENT) {
                            if (curveSpot.getIntrinsicHeight() < 0) {
                                height = GYDisplayUtils.dp2px(getContext(), 8);
                            } else {
                                height = curveSpot.getIntrinsicHeight();
                            }
                        } else {
                            height = curveSpotHeight;
                        }
                        spotBitmap = GYDisplayUtils.toBitmap(curveSpot, Math.round(width), Math.round(height));
                        Rect rect = new Rect();
                        for (SpotBean spotBean : spotBeanList) {
                            if (spotBean.isDrawSpot()) {
                                rect.set(Math.round(spotBean.getX() - width / 2), Math.round(spotBean.getY() - height / 2), Math.round(spotBean.getX() + width / 2), Math.round(spotBean.getY() + height / 2));
                                canvas.drawBitmap(spotBitmap, null, rect, paint);
                            }
                        }
                    }
                    //写提示信息
                    if (tipLocation != TipLocation.NONE) {
                        for (SpotBean spotBean : spotBeanList) {
                            int location;
                            if (tipLocation == TipLocation.NORMAL) {
                                if (spotBean.getY() >= pointY / 2) {
                                    location = TipLocation.TOP;
                                } else {
                                    location = TipLocation.BOTTOM;
                                }
                            } else {
                                location = tipLocation;
                            }
                            float y = spotBean.getY();
                            float spotHeight = 0;
                            if (spotBitmap != null) {
                                spotHeight = spotBitmap.getHeight();
                            }
                            switch (location) {
                                case TipLocation.TOP:
                                    y = spotBean.getY() - spotHeight / 2 - GYPaintUtils.newTextBuilder().setTextSize(tipTextSize).build().getBottom() - tipTextMargin;
                                    break;
                                case TipLocation.BOTTOM:
                                    y = spotBean.getY() + spotHeight / 2 + GYPaintUtils.newTextBuilder().setTextSize(tipTextSize).build().getTop() + tipTextMargin;
                                    break;
                            }
                            paint = new Paint();
                            paint.setTextAlign(Paint.Align.CENTER);
                            paint.setTextSize(tipTextSize);
                            paint.setColor(tipTextColor);
                            canvas.drawText(String.valueOf(spotBean.getNumber()), spotBean.getX(), y, paint);
                        }
                    }
                }
                break;
            case DisplayStyle.COLUMN://画柱形
                break;
        }
    }

    private float getY(Long number) {
        if (number == 0) {
            return pointY;
        } else if (number > 0) {
            for (int i = 0; i < yNumberList.size(); i++) {
                Long yNumber = yNumberList.get(i);
                if (number < yNumber) {
                    if (i == 0) {
                        float proportion = (float) number / yNumber;
                        return pointY - yFirstSpacing * proportion;
                    } else {
                        float proportion = (float) (number - yNumberList.get(i - 1)) / ((yNumber - yNumberList.get(i - 1)));
                        return yTextYList.get(i - 1) - ySpacing * proportion;
                    }
                } else if (number.equals(yNumber)) {
                    return yTextYList.get(i);
                }
            }
        }
        return 0;
    }

    private Path curvePath(List<SpotBean> spotBeanList) {
        Path path = new Path();
        path.moveTo(spotBeanList.get(0).getX(), spotBeanList.get(0).getY());
        for (int i = 1; i < spotBeanList.size(); i++) {
            float lastX = spotBeanList.get(i - 1).getX();
            float lastY = spotBeanList.get(i - 1).getY();
            float x = spotBeanList.get(i).getX();
            float y = spotBeanList.get(i).getY();
            path.quadTo(lastX + xSpacing / 4, lastY, (lastX + x) / 2, (lastY + y) / 2);
            path.quadTo(x - xSpacing / 4, y, x, y);
        }
        return path;
    }

    /**
     * 画扇形图
     *
     * @param canvas
     */
    private void drawSector(Canvas canvas) {
        //计算圆点坐标和半径
        float pointX;
        float pointY;
        float radius;
        if (getWidth() > getHeight()) {
            pointX = getHeight() / 2;
            pointY = getHeight() / 2;
            radius = getHeight() / 2;
        } else {
            pointX = getWidth() / 2;
            pointY = getWidth() / 2;
            radius = getWidth() / 2;
        }
        switch (circleDisplay) {
            case SectorDisplay.START:
                break;
            case SectorDisplay.CENTER:
                if (getWidth() > getHeight()) {
                    pointX = getWidth() / 2;
                } else {
                    pointY = getHeight() / 2;
                }
                break;
            case SectorDisplay.END:
                if (getWidth() > getHeight()) {
                    pointX = getWidth() - radius;
                } else {
                    pointY = getHeight() - radius;
                }
                break;
        }
        initSectorColorList();
        float nowDegrees = sectorStartDegree;
        paint.setAntiAlias(true);// 抗锯齿
        paint.setStyle(Paint.Style.FILL);// Style.FILL: 实心, STROKE:空心, FILL_OR_STROKE:同时实心与空心
//        paint.setStrokeCap(Paint.Cap.ROUND);// 画笔样式：圆形 Cap.ROUND, 方形 Cap.SQUARE
//        paint.setStrokeJoin(Paint.Join.ROUND);// 平滑效果
//        paint.setStrokeWidth(15);
        long sectorAll = 0;
        for (Long l : numberList) {
            sectorAll += l;
        }
        RectF rect = new RectF(Math.round(pointX - radius), Math.round(pointY - radius), Math.round(pointX + radius), Math.round(pointY + radius));
//        long sectorDegreeAll = 360 - sectorSpacingDegree * numberList.size();
        long sectorDegreeAll = 360;
        for (int i = 0; i < numberList.size(); i++) {
            paint.setColor(sectorColorList.get(i));
            float sectorDegree = (float) (numberList.get(i) * 1.0 / sectorAll) * sectorDegreeAll;
            if (i == numberList.size() - 1) {
                if (nowDegrees + sectorDegree != sectorDegreeAll + sectorStartDegree) {
                    nowDegrees = sectorDegreeAll + sectorStartDegree - sectorDegree;
                }
            }
            canvas.drawArc(rect, nowDegrees, sectorDegree, true, paint);
            nowDegrees += sectorDegree;
        }
    }

    private void initSectorColorList() {
        if (sectorColorList.size() == 0) {
            sectorColorList.add(Color.GREEN);
        }
        List<Integer> integerList = new ArrayList<>();
        for (Integer color : sectorColorList) {
            if (sectorColorList.size() + integerList.size() < numberList.size()) {
                integerList.add(color);
            } else {
                break;
            }
        }
        sectorColorList.addAll(integerList);
        if (sectorColorList.size() < numberList.size()) {
            initSectorColorList();
        }
    }

    private float xFirstSpacing() {
        return xFirstSpacing == WRAP_CONTENT ? xSpacing : xFirstSpacing;
    }

    private float yFirstSpacing() {
        return yFirstSpacing == WRAP_CONTENT ? ySpacing : yFirstSpacing;
    }

    private static class SpotBean {
        public static SpotBean newInstance() {
            return new SpotBean();
        }

        float x;
        float y;
        boolean drawSpot;
        long number;

        public float getX() {
            return x;
        }

        public SpotBean setX(float x) {
            this.x = x;
            return this;
        }

        public float getY() {
            return y;
        }

        public SpotBean setY(float y) {
            this.y = y;
            return this;
        }

        public SpotBean setDrawSpot(boolean drawSpot) {
            this.drawSpot = drawSpot;
            return this;
        }

        public boolean isDrawSpot() {
            return drawSpot;
        }

        public long getNumber() {
            return number;
        }

        public SpotBean setNumber(long number) {
            this.number = number;
            return this;
        }
    }
}
